# Copyright (c) 2025 Huawei Technologies Co., Ltd.
# openUBMC is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#         http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.
import os

from conans import ConanFile, tools, CMake, AutoToolsBuildEnvironment


class GrpcConan(ConanFile):
    name = "grpc"
    description = "Google's RPC library and framework"
    settings = "os", "compiler", "build_type", "arch"
    exports_sources = ["permissions.ini"]
    options = {
        "shared": [True, False],
        "fPIC": [True, False],
        "with_zlib": [True, False],
        "with_openssl": [True, False],
        "with_cares": [True, False],
        "with_abseil": [True, False],
        "build_codegen": [True, False]
    }
    default_options = {
        "shared": True,
        "fPIC": True,
        "with_zlib": False,
        "with_openssl": False,
        "with_cares": True,
        "with_abseil": True,
        "build_codegen": True
    }
    generators = "cmake"
    _cmake = None

    @property
    def _source_subfolder(self):
        return "source_subfolder"

    def requirements(self):
        requires = self.conan_data.get("requires", {}).get(self.version, [])
        for req in requires:
            self.requires(req)

    def build_requirements(self):
        if os.path.exists('/home/bin/protoc') and os.path.exists('/home/bin/grpc_cpp_plugin'):
            return
        requires = self.conan_data.get("tool_requires", {}).get(self.version,[])
        for req in requires:
            self.tool_requires(req)

    def source(self):
        git = tools.Git(verify_ssl=False)
        git.clone(**self.conan_data["sources"][self.version])

    def build(self):
        cmake = self._configure_cmake()
        cmake.build()

    def package(self):
        cmake = self._configure_cmake()
        cmake.install()
        self.copy("permissions.ini", src="", dst="")

    def package_info(self):
        self.cpp_info.libs = tools.collect_libs(self)

    def _configure_cmake(self):
        if self._cmake:
            return self._cmake
        self._cmake = CMake(self)
        os.environ['CFLAGS'] = os.getenv('CFLAGS') + " -D_FORTIFY_SOURCE=2 -Os -w"
        os.environ['CXXFLAGS'] = os.getenv('CXXFLAGS') + " -D_FORTIFY_SOURCE=2 -Os -w"
        absl_rootpath = self.deps_cpp_info["abseil"].rootpath
        protobuf_rootpath = self.deps_cpp_info["protobuf"].rootpath
        cares_rootpath = self.deps_cpp_info["c_ares"].rootpath
        if os.path.exists('/home/bin/protoc') and os.path.exists('/home/bin/grpc_cpp_plugin'):
            lib_path = '/home/lib'
            os.environ['LD_LIBRARY_PATH'] = f'{lib_path}:{os.environ.get('LD_LIBRARY_PATH', '')}'
            self._cmake.definitions['_gRPC_PROTOBUF_PROTOC_EXECUTABLE'] = '/home/bin/protoc'
            self._cmake.definitions['CMAKE_PROGRAM_PATH'] = '/home/bin/'
        else:
            lib_path = os.path.join(self.dependencies.build['protobuf'].package_folder, 'lib')
            os.environ['LD_LIBRARY_PATH'] = f'{lib_path}:{os.environ.get('LD_LIBRARY_PATH', '')}'
            protoc_path = os.path.join(self.dependencies.build['protobuf'].package_folder, 'bin/protoc')
            self._cmake.definitions['_gRPC_PROTOBUF_PROTOC_EXECUTABLE'] = protoc_path
        re2_rootpath = self.deps_cpp_info["re2"].rootpath
        absl_dir = os.path.join(absl_rootpath, "lib", "cmake", "absl")
        re2_dir = os.path.join(re2_rootpath, "lib", "cmake", "re2")
        protobuf_dir = ""
        if self.settings.arch == "x86_64":
            protobuf_dir = os.path.join(protobuf_rootpath, "lib")
        else:
            protobuf_dir = os.path.join(protobuf_rootpath, "usr", "lib64")
        if not self.settings.build_type == "Dt":
            self.run(
                "sed -i 's/set(gRPC_INSTALL_LIBDIR \"lib\"/set(gRPC_INSTALL_LIBDIR \"usr\/lib64\"/' CMakeLists.txt")
            self._cmake.definitions["BUILD_SHARED_LIBS"] = "OFF"
        self._cmake.definitions["gRPC_INSTALL"] = True
        self._cmake.definitions["gRPC_BUILD_TEST"] = False
        self._cmake.definitions["gRPC_BUILD_CSHARP_EXT"] = False
        self._cmake.definitions["gRPC_ZLIB_PROVIDER"] = "package"
        self._cmake.definitions["gRPC_SSL_PROVIDER"] = "package"
        self._cmake.definitions["gRPC_CARES_PROVIDER"] = "package"
        self._cmake.definitions["gRPC_ABSL_PROVIDER"] = "package"
        self._cmake.definitions["gRPC_RE2_PROVIDER"] = "package"
        self._cmake.definitions["gRPC_PROTOBUF_PROVIDER"] = "package"
        self._cmake.definitions["CMAKE_CXX_STANDARD"] = 17
        self._cmake.definitions["CMAKE_PREFIX_PATH"] = f"{protobuf_rootpath};{re2_dir};{cares_rootpath};{absl_dir};"
        self._cmake.definitions["CMAKE_PREFIX_PATH"] += protobuf_dir
        self._cmake.configure(args=["--no-warn-unused-cli"])
        return self._cmake